﻿#region using
using System;
using System.Collections.Generic;
#endregion using

namespace MpSoft.Collections.Generic
{
    /*public static class EnumerableExt
    {
        public static IEnumerable<T> Part<T>(this IEnumerable<T> source,int index,int length)
        {
            return new EnumerablePartExt<T>(source,index,length);
        }

        public static IEnumerable<T> Part<T>(this IEnumerable<T> source,int index)
        {
            return new EnumerablePartExt<T>(source,index,int.MaxValue);
        }
    }*/

    public class EnumerablePart<T>:IEnumerable<T>
    {
        public EnumerablePart(IEnumerable<T> source,int index):this(source,index,int.MaxValue)
        {}

        PartEnumerator enumer;
        public EnumerablePart(IEnumerable<T> source,int index,int length)
        {
            enumer=new PartEnumerator(source,index,length);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return enumer;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return enumer;
        }

        class PartEnumerator:IEnumerator<T>
        {
            IEnumerator<T> _source;
            int _currIndex,_length,_minIndex;
            internal PartEnumerator(IEnumerable<T> source,int index,int length)
            {
                _source=source.GetEnumerator();
                _minIndex=index;
                _length=length;
                Reset();
            }

            public T Current
            {
                get { return _source.Current; }
            }

            object System.Collections.IEnumerator.Current
            {
                get { return _source.Current; }
            }

            public bool MoveNext()
            {
                if (_currIndex>=_length)
                    return false;

                bool result=_source.MoveNext();
                if (result)
                    _currIndex++;
                return result;
            }

            public void Reset()
            {
                _source.Reset();
                if (_minIndex!=0)
                    for (int a=0;a<_minIndex;a++)
                        _source.MoveNext();
                _currIndex=0;
            }

            public void Dispose()
            {
                _source.Dispose();
            }
        }
    }
}
